﻿using System;
using System.Collections.Generic;
using MLog.Core.Appender;

namespace MLog.Core {
    public class Logger : BaseLogger {
        private readonly List<IAppender<LoggerEvent>> _appenders = new List<IAppender<LoggerEvent>>();

        public void AddAppend(IAppender<LoggerEvent> appender) {
            _appenders.Add(appender);
        }

        public void RemoveAppend(string name) {
            for (var i = _appenders.Count - 1; i >= 0; i--)
                if (Equals(_appenders[i].Name, name))
                    _appenders.RemoveAt(i);
        }

        public override void LogEvent(LoggerEvent @event) {
            DoAppend(@event);
        }

        private void DoAppend(LoggerEvent @event) {
            for (var i = 0; i < _appenders.Count; i++) _appenders[i].DoAppend(@event);
        }

        public virtual void ApplyConfig(string name, Node config) {
            Name = name;
            var rootConfig = LoggerConfiguration.GetLoggerNearest("root");
            var def        = rootConfig.GetAttr("level", Constants.DefaultLevel);
            var level      = config.GetAttr("level", def);
            Level = (LogLevel) Enum.Parse(typeof(LogLevel), level, true);
            var rootChild      = rootConfig.Child;
            var rootChildCount = rootConfig.Child == null ? 0 : rootConfig.Child.Count;
            var myChildCount   = config.Child     == null ? 0 : config.Child.Count;

            Node[] allChild = null;
            if (Constants.MergerDefaultConfig) {
                allChild = new Node[rootChildCount + myChildCount];
                if (rootChild    != null) rootChild.CopyTo(allChild);
                if (config.Child != null) config.Child.CopyTo(allChild, rootChildCount);
            }
            else {
                allChild = config.Child.ToArray();
            }

            if (allChild.Length > 0)
                for (var i = 0; i < allChild.Length; i++) {
                    var c = allChild[i];
                    if ("appender-ref".Equals(c.Name)) {
                        var appenderRef = c.GetAttr("ref");
#if UNITY_5_3_OR_NEWER
                        UnityEngine.Assertions.Assert.IsNotNull(appenderRef, "MLog: xml error!");
#endif
                        var appenderConfig = LoggerConfiguration.GetAppender(appenderRef);
                        var appender       = BaseAppender<LoggerEvent>.Create(appenderConfig);
                        AddAppend(appender);
                    }
                }
        }
    }
}